package top.xchch.workdemo.func03;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

/**
 * 线程同步方式三: 信号量控制线程间协作, 同时实现main线程等待
 *
 * 背景. 10个人过桥, 每次只允许3个人过桥, 每个人过桥时间为500-600毫秒, 计算总的过桥时间
 *
 * @author sai.zhang
 * @date 2021-10-17 19:29
 */
public class Main {

    private static ExecutorService es = Executors.newFixedThreadPool(4);

    private static Semaphore semaphore = new Semaphore(3);

    private static final int PERSON_NUM = 10;

    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        List<Future<String>> futureList = new ArrayList<>();
        for (int i = 0; i < PERSON_NUM; i++) {
            Person p = new Person("p-" + i);
            Future<String> future = es.submit(() -> {
                semaphore.acquire();
                try {
                     return p.crossBridge(new Random().nextInt(100) + 500);
                }finally {
                    semaphore.release();
                }
            });

            futureList.add(future);
        }

        for (Future<String> future: futureList) {
            try {
                System.out.println(future.get());
            } catch (InterruptedException | ExecutionException e) {
                System.out.println("出错了, " + e.getMessage());
            }
        }
        System.out.println("使用时间: "+ (System.currentTimeMillis() - start) + " ms");

        es.shutdown();
    }
}

class Person {

    public String name;

    public Person(String name) {
        this.name = name;
    }

    public String crossBridge(int usedTime) {
        try {
            Thread.sleep(usedTime);
        } catch (InterruptedException e) {
            System.out.println("出错了, " + e.getMessage());
        }
        return this.name + "过河完成, 用时 " +  usedTime + " ms";

    }

}
